<template>
  <div class="updateChipContent">
    <el-drawer
      :with-header="false"
      :close-on-press-escape="false"
      :wrapper-closable="false"
      :visible.sync="drawerVisible"
      size="800px"
    >
      <div class="drawerForm">
        <div class="pageTitle">
          <div class="titleText">更新芯片</div>
        </div>
        <el-form
          ref="chipForm"
          class="myForm"
          :model="chipForm"
          label-width="138px"
          :rules="chipRules"
          label-suffix="："
        >
          <el-form-item label="当前芯片定义文件">
            <el-button type="primary" @click="handleDownload">下载芯片文件</el-button>
          </el-form-item>
          <el-form-item label="更新芯片文件" prop="chipDefinitionFiles">
            <el-upload
              ref="chipDefinitionFiles"
              class="upload-demo"
              action="#"
              :limit="1"
              :file-list="chipForm.chipDefinitionFiles"
              :on-exceed="(files) => handleExceed(files, 'chipDefinitionFiles')"
              :accept="'.json'"
              :on-remove="() => handleRemove('chipDefinitionFiles')"
              :http-request="(require) => handleUploadFiles(require, 'chipDefinitionFiles')"
            >
              <div slot="tip" class="el-upload__tip">只能上传.json文件，且单个文件不超过 20 MB</div>
              <el-button size="small" plain>
                上传文件
                <i class="el-icon-upload el-icon--right" />
              </el-button>
            </el-upload>
          </el-form-item>
          <el-form-item label="文件规则检查">
            <div class="percentageBox">
              <el-progress
                :percentage="fileRulesCheckPercentage"
                :status="getPercentageStatus(fileRulesCheckResult)"
                :show-text="false"
              ></el-progress>
              <template v-if="fileRulesCheckResult === 'fail'">
                <i class="el-icon-circle-close failResult" />
                <el-button type="primary" class="downloadBtn" @click="handleView">查看检查结果</el-button>
              </template>
              <i v-else-if="fileRulesCheckResult === 'success'" class="el-icon-circle-check successResult" />
            </div>
          </el-form-item>

          <el-form-item v-if="startParameterConfigurationRuleGeneration" label="参数配置规则生成">
            <div class="percentageBox">
              <el-progress
                :percentage="parameterConfigurationRuleGenerationPercentage"
                :show-text="false"
                :status="getPercentageStatus(parameterConfigurationRuleGenerationResult)"
              ></el-progress>

              <template v-if="parameterConfigurationRuleGenerationResult === 'fail'">
                <i class="el-icon-circle-close failResult" />
              </template>
              <i
                v-else-if="parameterConfigurationRuleGenerationResult === 'success'"
                class="el-icon-circle-check successResult"
              />
            </div>
          </el-form-item>
        </el-form>
        <div class="drawerFooter" align="right">
          <el-button :loading="loading" @click="handleClose">取消</el-button>
          <el-button :loading="loading" type="primary" @click="handleSubmit">确认</el-button>
        </div>
      </div>
    </el-drawer>

    <el-dialog
      :title="'参数配置规则'"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      :visible.sync="ruleDialogVisible"
      width="564px"
    >
      <el-table
        :height="500"
        :show-header="false"
        :data="parameterConfigurationRuleSetList"
        border
        style="width: 100%"
      >
        <el-table-column prop="ruleSetName" label="规则集名称">
          <template slot-scope="scope">{{ scope.row.ruleSetName }}规则集</template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="100" align="center">
          <template slot-scope="scope">
            <el-button type="text" size="small" @click="handleClick(scope.row)">查看</el-button>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleClose">关闭</el-button>
      </span>
    </el-dialog>
    <testResult ref="testResult" />
    <ruleSetDetail
      v-if="showRuleSetDetail"
      ref="ruleSetDetail"
      type="parameterConfigure"
      @close="showRuleSetDetail = false"
    />
  </div>
</template>

<script>
import { uploadFile } from '@/api/system-management'
import { updateChipByFile } from '@/api/project-management'
import { fileRuleCheck, initParameterConfiguration } from '@/api/rule-management'
import { downLoadFile, fileDownload } from '@/utils/download'
import testResult from './testResult'
import ruleSetDetail from '@/views/rule-management/components/ruleSetDetail.vue'
import defaultSettings from '@/settings'
import { generateUUID, postMessage, receivedMessage } from '@/utils/index'
export default {
  name: 'DpagmWebUpdateChip',
  components: { testResult, ruleSetDetail },
  data() {
    return {
      drawerVisible: false,
      loading: false,
      notPassDataList: [],
      ruleDialogVisible: false,
      chipDefinitionFiles: [],
      chipForm: { chipDefinitionFiles: [] },
      chipRules: {
        chipDefinitionFiles: [{ required: true, message: '请上传更新芯片文件', trigger: 'blur' }]
      },
      fileRulesCheckResult: 'running',
      fileRulesCheckPercentage: 0,
      startParameterConfigurationRuleGeneration: false,
      parameterConfigurationRuleGenerationResult: 'running',
      parameterConfigurationRuleGenerationPercentage: 0,
      parameterConfigurationRuleSetList: [],
      timer: null,
      showRuleSetDetail: false,
      uploadFileRequestId: generateUUID(),
      uploadFileSetting: {},
      updateChipByFileRequestId: generateUUID(),
      downloadFileRequestId: generateUUID(),
      fileRuleCheckRequestId: generateUUID(),
      initParameterConfigurationRequestId: generateUUID()
    }
  },
  mounted() {
    receivedMessage(this.dataHandle)
  },

  methods: {
    dataHandle(result) {
      let self = this
      let e = defaultSettings.isWPF ? result : { data: JSON.parse(result) }
      if (e.data.webInfo.requestId === self.uploadFileRequestId) {
        self.afterUpload(e.data.response)
      } else if (e.data.webInfo.requestId === self.updateChipByFileRequestId) {
        let res = e.data.response
        if (res.success) {
          self.afterUpdateChip(res)
        } else {
          self.timer && clearInterval(self.timer)
          self.parameterConfigurationRuleGenerationResult = 'fail'
          self.loading = false
        }
      } else if (e.data.webInfo.requestId === self.downloadFileRequestId) {
        // const blob = new Blob([JSON.stringify(e.data.response, null, 2)], { type: 'text/plain;charset=utf-8' })
        // saveAs(blob, self.chipDefinitionFiles[0].fileName)
        let res = e.data.response
        if (res.success) {
          var bytes = new Uint8Array(
            window
              .atob(res.data)
              .split('')
              .map(function (c) {
                return c.charCodeAt(0)
              })
          )
          res.data = bytes
          fileDownload(res)
        } else {
          self.$message.error(res.message)
        }
      } else if (e.data.webInfo.requestId === self.fileRuleCheckRequestId) {
        let res = e.data.response
        if (res.success) {
          self.timer && clearInterval(self.timer)
          self.notPassDataList = res.data.notPassDataList
          if (self.notPassDataList.length === 0) {
            self.fileRulesCheckResult = 'success'
            self.fileRulesCheckPercentage = 100
          } else {
            self.fileRulesCheckResult = 'fail'
          }
        } else {
          self.notPassDataList = []
          self.timer && clearInterval(self.timer)
          self.fileRulesCheckResult = 'fail'
        }
      } else if (e.data.webInfo.requestId === self.initParameterConfigurationRequestId) {
        let res = e.data.response
        if (res.success) {
          self.$nextTick(() => {
            self.$refs.ruleSetDetail.is('view', res.data)
          })
        } else {
          self.$message.error(res.message)
        }
      }
    },
    is(row) {
      this.startParameterConfigurationRuleGeneration = false
      this.drawerVisible = true
      this.fileRulesCheckResult = 'running'
      this.fileRulesCheckPercentage = 0
      this.parameterConfigurationRuleGenerationResult = 'running'
      this.parameterConfigurationRuleGenerationPercentage = 0
      this.loading = false
      this.dialogVisible = true
      this.chipDefinitionFiles = row.chipDefinitionFiles
      this.chipForm = { type: row.type, chipId: row.chipId, chipDefinitionFiles: [] }
      this.$nextTick(() => {
        this.$refs.chipForm.clearValidate()
      })
    },
    getPercentageStatus(status) {
      let result = ''
      switch (status) {
        case 'success':
          result = 'success'
          break
        case 'fail':
          result = 'exception'
          break
        default:
          result = undefined
      }
      return result
    },
    // 查看检查结果
    handleView() {
      this.$refs.testResult.is({
        chipDefinitionFiles: this.chipForm.chipDefinitionFiles,
        notPassDataList: this.notPassDataList
      })
    },
    handleClose() {
      this.$refs.chipDefinitionFiles.clearFiles()
      this.ruleDialogVisible = false
      this.drawerVisible = false
    },
    handleClick(row) {
      this.showRuleSetDetail = true
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.initParameterConfigurationRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/ruleSet/initParameterConfiguration',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: { ruleSetId: row.ruleSetId },
          WebInfo: {
            requestId: this.initParameterConfigurationRequestId
          }
        }
        postMessage(message)
      } else {
        initParameterConfiguration({ ruleSetId: row.ruleSetId }).then((res) => {
          this.$nextTick(() => {
            this.$refs.ruleSetDetail.is('view', res.data)
          })
        })
      }
    },
    handleDownload() {
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.downloadFileRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/files/download',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: { files: this.chipDefinitionFiles },
          WebInfo: {
            requestId: this.downloadFileRequestId
          }
        }
        postMessage(message)
      } else {
        downLoadFile(
          process.env.VUE_APP_BASE_API + this.chipDefinitionFiles?.[0]?.path,
          this.chipDefinitionFiles?.[0]?.fileName
        )
      }
    },
    handleExceed(files, fileName) {
      this.$refs[fileName].clearFiles()
      this.handleUploadFiles({ file: files[0] }, fileName)
    },
    handleRemove(fileName) {
      this.fileRulesCheckPercentage = 0
      this.fileRulesCheckResult = 'running'
      this.parameterConfigurationRuleGenerationPercentage = 0
      this.parameterConfigurationRuleGenerationResult = 'running'
      this.chipForm[fileName] = []
    },
    // 上传前校验
    handleCheck(params) {
      var suffix = params.file.name.substring(params.file.name.lastIndexOf('.')) // .txt
      const isLimit = params.file.size / 1024 / 1024 < 20
      var accept = ['.json']
      if (accept.includes(suffix)) {
        if (!isLimit) {
          this.$notify.error('上传文件大小不能超过 20MB!')
          return false
        } else {
          return true
        }
      } else {
        this.$notify.error('上传文件不符合上传格式!')
        return false
      }
    },
    // 图片上传
    handleUploadFiles(require, fileName) {
      this.fileRulesCheckPercentage = 0
      this.fileRulesCheckResult = 'running'
      this.parameterConfigurationRuleGenerationPercentage = 0
      this.parameterConfigurationRuleGenerationResult = 'running'
      let fileDom = this.$refs[fileName].uploadFiles
      let check = this.handleCheck(require)
      if (!check) {
        fileDom.splice(fileDom.length - 1, 1)
        return
      }
      this.uploadFileSetting = {
        fileName,
        require
      }
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        let self = this
        this.uploadFileRequestId = generateUUID()
        let reader = new FileReader() // new一个FileReader实例
        reader.readAsDataURL(require.file)
        reader.onload = function () {
          //   读取文件获得的对象
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/upload',
            RequestMethod: 'POST',
            Headers: {
              // contentType: 'multipart/form-data'
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: {
              fileName: require.file.name,
              fileContent: reader.result.split(',')[1]
            },
            WebInfo: {
              requestId: self.uploadFileRequestId
            }
          }
          postMessage(message)
        }
      } else {
        let formData = new FormData()
        formData.append('file', require.file)
        uploadFile(formData)
          .then((res) => {
            this.afterUpload(res)
          })
          .catch(() => {
            this.$notify.error('上传失败')
          })
      }
    },
    afterUpload(res) {
      this.chipForm[this.uploadFileSetting.fileName] = [
        {
          uid: this.uploadFileSetting.require.file.uid,
          fileType: res.data.fileType,
          name: res.data.name,
          fileName: res.data.name,
          url: res.data.url,
          path: res.data.url,
          base64: 'data:image/png;base64,' + res.data.base64
        }
      ]
      this.$refs.chipForm.validateField(this.uploadFileSetting.fileName)
      this.notPassDataList = []
      this.timer = setInterval(() => {
        this.fileRulesCheckPercentage += 10
        if (this.fileRulesCheckPercentage === 90) {
          this.timer && clearInterval(this.timer)
        }
      }, 50)
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.fileRuleCheckRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/chip/fileRuleCheck',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: {
            filePath: res.data.url,
            ruleSetType: this.chipForm.type
          },
          WebInfo: {
            requestId: this.fileRuleCheckRequestId
          }
        }
        postMessage(message)
      } else {
        fileRuleCheck({
          filePath: res.data.url,
          ruleSetType: this.chipForm.type
        })
          .then((res) => {
            this.timer && clearInterval(this.timer)
            this.notPassDataList = res.data.notPassDataList
            if (this.notPassDataList.length === 0) {
              this.fileRulesCheckResult = 'success'
              this.fileRulesCheckPercentage = 100
            } else {
              this.fileRulesCheckResult = 'fail'
            }
          })
          .catch(() => {
            this.notPassDataList = []
            this.timer && clearInterval(this.timer)
            this.fileRulesCheckResult = 'fail'
          })
      }
    },
    handleSubmit() {
      if (this.fileRulesCheckResult === 'fail') {
        this.$notify.error('芯片定义文件未通过文件规则检查')
        return
      }
      this.$refs.chipForm.validate((valid) => {
        if (valid) {
          this.loading = true
          this.startParameterConfigurationRuleGeneration = true
          this.timer = setInterval(() => {
            this.parameterConfigurationRuleGenerationPercentage += 10
            if (this.parameterConfigurationRuleGenerationPercentage === 90) {
              this.timer && clearInterval(this.timer)
            }
          }, 200)
          let params = {
            ...this.chipForm,
            chipDefinitionFiles: this.chipForm.chipDefinitionFiles.map((item) => {
              return {
                ...item,
                base64: ''
              }
            })
          }
          if (defaultSettings.isWPF || defaultSettings.isCEF) {
            this.updateChipByFileRequestId = generateUUID()
            let message = {
              RequestUrl: process.env.VUE_APP_URL + '/chip/updateChipByFile',
              RequestMethod: 'POST',
              Headers: {
                contentType: 'application/json'
              },
              QueryParameter: {},
              RequestBody: params,
              WebInfo: {
                requestId: this.updateChipByFileRequestId
              }
            }
            postMessage(message)
          } else {
            updateChipByFile(params)
              .then((res) => {
                this.afterUpdateChip(res)
              })
              .catch(() => {
                this.timer && clearInterval(this.timer)
                this.parameterConfigurationRuleGenerationResult = 'fail'
                this.loading = false
              })
          }
        }
      })
    },
    afterUpdateChip(res) {
      this.loading = false
      this.timer && clearInterval(this.timer)
      if (res.success) {
        this.$emit('refresh', this.chipForm.type)
        this.ruleDialogVisible = true
        this.parameterConfigurationRuleSetList = res.data
        this.parameterConfigurationRuleGenerationResult = 'success'
        this.parameterConfigurationRuleGenerationPercentage = 100
        this.$notify.success('修改芯片文件成功')
      } else {
        this.parameterConfigurationRuleGenerationResult = 'fail'
        this.$notify.error(res.message)
      }
    }
  }
}
</script>

<style lang="less" scoped>
.updateChipContent {
  .drawerForm {
    display: flex;
    flex-direction: column;
    height: 100%;
    .pageTitle {
      padding: 15px;
      font-size: 16px;
      color: #333;
      font-weight: bold;
      .titleText {
        display: inline;
        padding-right: 20px;
        padding-left: 5px;
      }
    }
    .myForm {
      height: calc(100% - 100px);
      margin: 0px 20px;
      display: flex;
      flex-direction: column;
      overflow-y: auto;
      padding-right: 7px;
    }
    .drawerFooter {
      padding: 0 20px;
      float: right;
    }
  }
}

.percentageBox {
  height: 32px;
  display: flex;
  padding-right: 5px;
  align-items: center;
  .el-progress {
    flex: 1;
    padding-right: 10px;
  }
  .successResult {
    color: #67c23a;
  }
  .failResult {
    color: #f56c6c;
  }
  .downloadBtn {
    margin-left: 10px;
    // padding-right: 0;
  }
}
</style>
